﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using log4net;

namespace TruyenTranhCrawler.Utils
{
    public class Process
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private static readonly HtmlParser Parser = new HtmlParser();

        #region RejectMarks/ Xóa dấu tiếng việt

        readonly static string[] PatternMarks = new string[7] { "a|(Á|À|Ạ|Ả|Ã|Â|Ă|Ấ|Ầ|Ậ|Ẩ|Ẫ|Ắ|Ằ|Ặ|Ẳ|Ẵ)", "o|(Ó|Ò|Ọ|Ỏ|Õ|Ô|Ố|Ồ|Ộ|Ổ|Ỗ|Ơ|Ớ|Ờ|Ợ|Ở|Ỡ)", "e|(é|è|ẻ|ẹ|ẽ|ê|ế|ề|ể|ệ|ễ)", "u|(ú|ù|ủ|ụ|ũ|ư|ứ|ừ|ử|ự|ữ)", "i|(í|ì|ỉ|ị|ĩ)", "y|(ý|ỳ|ỷ|ỵ|ỹ)", "d|đ" };
        /// <summary>
        /// Xoa dau tieng viet, giu nguyen cum tu
        /// </summary>
        public static string RejectMarksOnly(string sInput)
        {
            if (string.IsNullOrEmpty(sInput)) return "";
            foreach (string t in PatternMarks)
            {
                string replacer = t[0].ToString();
                sInput = Regex.Replace(sInput, t, replacer, (RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant));
            }
            return sInput;
        }
        /// <summary>
        /// Xóa dấu tiếng việt va các ký tự đặc biệt
        /// </summary>
        public static string RejectMarks(string sInput, string spaceReplacer = "-")
        {
            if (string.IsNullOrEmpty(sInput)) return "";
            foreach (string t in PatternMarks)
            {
                string replacer = t[0].ToString();
                sInput = Regex.Replace(sInput, t, replacer, (RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant));
            }
            sInput = Regex.Replace(sInput, @"[^A-Za-z0-9_\.~]+", spaceReplacer);
            return sInput;
        }

        /// <summary>
        /// Xóa tiếng việt, kí tự đặc biệt và chỗ trống thay bằng dấu '-'
        /// </summary>
        public static string ConvertToSafeMarks(string sInput)
        {
            if (string.IsNullOrEmpty(sInput)) return "";

            const string specialpattern = @"(""|'|@|&|,|:|;|/|#|%|~|\?|\.)";

            sInput = RejectMarks(sInput);

            sInput = Regex.Replace(sInput, specialpattern, HtmlParser.Patterns.SINGLE_SPACE,
                                   (RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant));

            sInput = Regex.Replace(sInput, HtmlParser.Patterns.MultiSpacePattern, HtmlParser.Patterns.SINGLE_SPACE,
                                   (RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant));

            sInput = Regex.Replace(sInput.Trim(), HtmlParser.Patterns.SINGLE_SPACE, "-",
                                   (RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant));

            sInput = Regex.Replace(sInput, "--", "-");
            if (sInput.EndsWith("-"))
                sInput = sInput.Substring(0, sInput.Length - 1);

            return sInput;
        }
        #endregion

        /// <summary>
        /// Fill absolute link
        /// </summary>
        /// <param name="domain">include http, example: http://truyengi.com</param>
        /// <param name="link"></param>
        /// <returns></returns>
        public static string FillAbsoluteLink(string domain, string link)
        {
            if (string.IsNullOrEmpty(link)) return "";
            if (!link.StartsWith("http"))
            {
                if (link.StartsWith("/"))
                    link = link.Remove(0, 1);

                if (!domain.EndsWith("/"))
                    domain += "/";
                link = domain + link;
            }
            return link;
        }


        public static string GetHtmlSources(string url)
        {
            var responseFromServer = "";

            try
            {
                var uri = new Uri(url);
                var request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "GET";
                request.AutomaticDecompression = DecompressionMethods.GZip;
                request.ContentType = "text/html; charset=utf-8";
                request.Host = uri.Host;
                request.Referer = url;
                request.KeepAlive = true;
                request.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22 AlexaToolbar/alxg-3.1";
                request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                request.Headers["X-Requested-With"] = "XMLHttpRequest";

                var response = (HttpWebResponse)request.GetResponse();

                var dataStream = response.GetResponseStream();
                if (dataStream != null)
                {
                    var reader = new StreamReader(dataStream);
                    responseFromServer = reader.ReadToEnd();
                    // Clean up the streams.
                    reader.Close();
                    dataStream.Close();
                }
                response.Close();
            }
            catch (Exception ex)
            {
                //Logger.Info("*** ERROR GetHtmlSources url=" + url + ": " + ex);
            }
            return responseFromServer;
        }
        public static string PostHtmlSources(string url, string datas)
        {
            var responseFromServer = "";

            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(datas);
                var uri = new Uri(url);
                var request = (HttpWebRequest)WebRequest.Create(uri);
                request.AutomaticDecompression = DecompressionMethods.GZip;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
                request.ContentLength = bytes.Length;
                request.Host = uri.Host;
                request.Referer = url;
                request.KeepAlive = true;
                request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36";
                request.Accept = "*/*";
                Stream dataStream = request.GetRequestStream();
                dataStream.Write(bytes, 0, bytes.Length);
                dataStream.Close();

                var response = request.GetResponse();
                var responseStream = response.GetResponseStream();
                if (responseStream != null)
                {
                    var reader = new StreamReader(responseStream);
                    responseFromServer = reader.ReadToEnd();
                    // Clean up the streams.
                    reader.Close();
                    responseStream.Close();
                }
                response.Close();
            }
            catch (Exception ex)
            {
                Logger.Info("*** ERROR GetHtmlSources url=" + url + ": " + ex);
            }
            return responseFromServer;
        }

        public static string GetRightLink(string hostName, string sSource)
        {
            var regex = new Regex("[ ]*(src|href)[ ]*=[ ]*\\\"(.*?)\\\"", RegexOptions.IgnoreCase);
            if (string.IsNullOrEmpty(sSource))
            {
                return null;
            }
            string str = sSource;

            foreach (Match match in regex.Matches(sSource))
            {
                string str3 = match.Groups[2].Value;
                if (!str3.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                {
                    string newValue = str3;
                    if (newValue.StartsWith("/"))
                    {
                        newValue = newValue.Remove(0, 1);
                    }
                    newValue = " " + match.Groups[1].Value + "=\"" + hostName + newValue + "\" ";
                    str = str.Replace(match.Value, newValue);
                }
            }
            return str;
        }

        public static string GetFirstImg(string sContent)
        {
            var imgs = Parser.GetContentInNode(sContent, "<img ", ">");
            if (imgs.Count > 0)
            {
                var srcs = Parser.GetProperty(imgs[0], "src");
                if (srcs.Count>1)
                {
                    return (from Match src in srcs where src.Value.IndexOf("18.jpg") < 0 select src.Groups[4].Value).FirstOrDefault();
                }
                else if (srcs.Count == 1)
                {
                    return srcs[0].Groups[4].Value;
                }
            }
            return null;
        }

        const string DateFormat = "dd/MM/yyyy";
        public static DateTime StringToDate(string sDate)
        {
            try
            {
                var split = sDate.Trim().Split(' ');
                return DateTime.ParseExact(split[0], DateFormat, System.Globalization.CultureInfo.InvariantCulture);
            }
            catch (Exception ex)
            {
                return DateTime.Now;
            }
        }        
    }
}
